package huawei_security_go

import (
	"crypto/sha256"
	"errors"
	"golang.org/x/crypto/pbkdf2"
	"strings"
)

var (
	rootKeySalt = []byte{2, 3, 69, 85, 100, 21, 33, 76, 12, 17, 63, 25, 53, 69, 8, 69}
)

const (
	rootHashIteration = 10000
	rootKeyLen        = 16
)

func getRootKeyInSha256(rootKeyRaw []byte) string {
	shaKey := pbkdf2.Key(rootKeyRaw, rootKeySalt, rootHashIteration, rootKeyLen, sha256.New)
	return Byte2HexString(shaKey)
}

func GetRootKey(systemParts []string, configParts []string) (string, error) {
	if len(configParts) < 1 || len(systemParts) < 1 {
		return "", errors.New("root key system parts or config parts invalid")
	}

	rootKeyRaw := StringCharCode2Byte(systemParts[0])
	for i := 1; i < len(systemParts); i++ {
		sysPart := StringCharCode2Byte(systemParts[i])
		rootKeyRaw = calculateXor(&rootKeyRaw, &sysPart)
	}

	for i := 0; i < len(configParts); i++ {
		cfgPart := StringCharCode2Byte(configParts[i])
		rootKeyRaw = calculateXor(&rootKeyRaw, &cfgPart)
	}

	rootKey := getRootKeyInSha256(rootKeyRaw)
	return strings.ToUpper(rootKey), nil
}

func calculateXor(part1 * []byte, part2 * []byte) []byte {
	// 长度相等时，默认 part1 为 longPart
	longPtr, shortPtr := part1, part2
	if len(*longPtr) < len(*shortPtr) {
		longPtr = part2
		shortPtr = part1
	}

	// 得到新数组，存储异或计算结果
	resBytes := *longPtr
	for i := 0; i < len(*shortPtr); i++ {
		resBytes[i] = (*shortPtr)[i] ^ resBytes[i]
	}

	return resBytes
}
